/********************************
* process reference
********************************/

#include "Framework.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string>
#include <sys/shm.h>

using namespace std;

// class ProcessTable
void ProcessTable::initializeProcessTable(string file)
{
	/* open file with read mode */
	FILE* fp = fopen(file.c_str(), "r");
	if(NULL == fp)
	{
		/* fatal log */
		cerr<<"fatal :open "<<PROCESS_LIST_FILE <<" error."<<endl;
		return ;
	}
	
	char* strline = NULL;
	size_t length;
	while(getline(&strline, &length, fp) != -1)
	{
		// comment line or white line
		if(strline[0] == '#' || strline[0] == ' ' ||
			strline[0] == '\n')
		{
			continue;
		}

		Process aProcess;
		char* token = strtok(strline, " \t");
		aProcess.setPath(token);
		token = strtok(NULL, " \t");
		aProcess.setName(token);
		token = strtok(NULL, " \t");
		aProcess.setStartTime(atoi(token));
		
		m_processTable.push_back(aProcess);

		// put process information in shared memory 
		this->addEntry(aProcess);
	}
	if(NULL != strline)
	{
		free(strline);
	}
}

void ProcessTable::addEntry(Process varProc)
{
	strncpy(m_sharedProcessTable[m_processTable.size() - 1].name, varProc.getName().c_str(), 63);
	m_sharedProcessTable[m_processTable.size() - 1].status = Process::st_stopped;
	
}

/* start all process */
void ProcessTable::startAll()
{
	for(size_t index = 0; index < m_processTable.size(); index ++)
	{
		m_processTable[index].start();
	}
}

/* stop all process */
void stopAll()
{
	
}

// constructor
ProcessTable::ProcessTable()
{
	// get shared memory
	int shmId = shmget(FIX_KEY_PTB, sizeof(ProcessTable::SharedProcessTable)*MAX_MSG_NUM, IPC_CREAT | 0666);
	if(shmId == -1)
	{
		cerr<<"shmget() failure :"<<errno<<endl;
		return ;
	}

	// attach to shared memory
	m_sharedProcessTable = (SharedProcessTable* )shmat(shmId, NULL, 0);
	if(m_sharedProcessTable == (void*)-1)
	{
		cerr<<"shmat() failure :"<<errno<<endl;
		return ;
	}

	memset(m_sharedProcessTable, 0x00, sizeof(ProcessTable::SharedProcessTable)*MAX_MSG_NUM);
}

// deconstructor
ProcessTable::~ProcessTable()
{
	shmdt(m_sharedProcessTable);
}

/******* Process **********/
pid_t Process::start()
{
	int pid_tmp ;
	pid_tmp = fork();
	if(pid_tmp == -1)
	{
		cout<<"fork failure :"<<errno<<endl;
		return -1;
	}
	
	if(pid_tmp == 0)
	{
		//child process
		int rtn = execlp(m_path.c_str(), m_name.c_str(), (char*)0);
		if(rtn < 0)
		{
			cout<<"execlp failure path("<<m_path<<") name("<<m_name<<"):"<<errno<<endl;
			return -2;
		}
	}
	else
	{
		//parent process
		m_pid = pid_tmp;
		
		/* sleep */
		sleep(m_startTime);
	}
}

void Process::stop()
{
	
}

